﻿using System;
using System.Collections.Generic;
using System.Text;
using LogSystem;
using Mopsicus.Plugins;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using XLua;
using Yoozoo.Utils;

namespace Yoozoo.Gameplay.YGUICustom
{
    public class YEmojiInputField : InputField
    {
        private StringBuilder emojiCharBuilder = new StringBuilder(32);

        private Dictionary<char, LuaFunction> singleInputCallback = new Dictionary<char, LuaFunction>();
        private LuaFunction onFocusCallback;

        private bool appendingString = false;
        
        //protected int m_CaretPositionCache = 0;
        //protected int m_CaretSelectPositionCache = 0;

        private string TAG = "Chat [C#] YEmojiInputField";
        

        public void AddSingleInputCallback(int charCode, LuaFunction callback)
        {
            Debug.Log(LogModule.Chat, TAG + " AddSingleInputCallback " + charCode);
            this.singleInputCallback[(char) charCode] = callback;
        }

        public void AddOnFocusCallback(LuaFunction callback)
        {
            Debug.Log(LogModule.Chat, TAG + " AddOnFocusCallback ");
            this.onFocusCallback = callback;
        }

#if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IPHONE)
        private StringBuilder mContentBuilder = new StringBuilder();
        private String originText = String.Empty;

        protected override void PreSubmitProcess()
        {
            //originText = m_Text;
            //m_Text = ConvertText(m_Text);
            //m_TextComponent.text = m_Text;
        }
        
#else
        protected override void Append(char input)
        {
            Debug.Log(LogModule.Chat, TAG + " " + this.GetType().Name + "Append char: " + input);

            if (!TouchScreenKeyboard.isSupported && !this.appendingString)
                ExecuteAppendCheck(input);

            // We do not currently support surrogate pairs
            if (char.IsSurrogate(input))
            {
                //UnityEngine.Debug.LogWarningFormat("{0} InputLog: char.IsSurrogate({1}) == true", TAG, input);
                emojiCharBuilder.Append(input);
                if (emojiCharBuilder.Length % 2 == 0)
                {
                    string key = null;
                    var utf32 = GStringUtils.Parse2UTF_32(emojiCharBuilder.ToString(), false);
                    //UnityEngine.Debug.LogWarningFormat("{0} InputLog: utf32: {1}", TAG, utf32);
                    for (var j = 0; j < utf32.Length; j += 8)
                    {
                        var hexStr = GStringUtils.GetValidHexString(utf32.Substring(j, 8));
                        //UnityEngine.Debug.LogWarningFormat("{0} InputLog: hexStr: {1}", TAG, hexStr);
                        if (!string.IsNullOrEmpty(hexStr))
                        {
                            if (key != null)
                                key = key + "-" + hexStr;
                            else
                                key = hexStr;

                            if (true) //EmojiCreator.GetInstance().HasEmoji(key)
                            {
                                emojiCharBuilder.Clear();
                                Append('[');
                                for (var k = 0; k < key.Length; k++)
                                    Append(key[k]);

                                Append(']');
                                break;
                            }
                        }
                        else
                        {
                            emojiCharBuilder.Clear();
                            break;
                        }
                    }
                }

                return;
            }

            if (readOnly || text.Length >= k_MaxTextLength)
                return;

            if (!InPlaceEditing())
                return;

            // If we have an input validator, validate the input first
            int insertionPoint = Math.Min(selectionFocusPosition, selectionAnchorPosition);
            if (onValidateInput != null)
                input = onValidateInput(text, insertionPoint, input);
            else if (characterValidation != CharacterValidation.None)
                input = Validate(text, insertionPoint, input);

            // If the input is invalid, skip it
            if (input == 0)
                return;

            //Debug.LogWarning(TAG + " EI AppendChar " + input);
            // Append the character and update the label
            Insert(input);
            emojiCharBuilder.Clear();
        }
#endif
        
        public override void OnSelect(BaseEventData eventData)
        {
            base.OnSelect(eventData);
            onFocusCallback?.Action(true);
        }
        
        public override void OnDeselect(BaseEventData eventData)
        {
            onFocusCallback?.Action(false);
            base.OnDeselect(eventData);
        }
        
        public override void AppendString(string str)
        {
            var cached = this.m_TouchKeyboardAllowsInPlaceEditing;
            this.m_TouchKeyboardAllowsInPlaceEditing = true;

            // 跑逻辑
            Append(str);
            
            this.m_TouchKeyboardAllowsInPlaceEditing = cached;

            // 刷新文本显示
            UpdateLabel();
            
            GetComponent<MobileInputField>().Text = this.m_Text;
        }

        public void Deselect()
        {
            if (EventSystem.current.currentSelectedGameObject == gameObject)
                EventSystem.current.SetSelectedGameObject(null);

            //DeactivateInputField();
        }
        
        protected override void Append(string input)
        {
            this.appendingString = true;
            base.Append(input);
            this.appendingString = false;
        }
        
        private void ExecuteAppendCheck(char c)
        {
            Debug.Log(LogModule.Chat, TAG + " ExecuteAppendCheck : " + c);
            LuaFunction callback;
            if (!this.singleInputCallback.TryGetValue(c, out callback))
                return;
            
            Debug.Log(LogModule.Chat, TAG + " ExecuteAppendCheck Success! c = " + c);
            callback?.Action(c);
        }
    }
}